#Binary parser template

import os, sys
from Sanae3D.lib.ModelObject import Model3D
from Sanae3D.lib.StructReader import StructReader

class FatalFake_STG(Model3D):

    def __init__(self, obj3D=None, outFile=None, inFile=None):
        
        super(FatalFake_STG,self).__init__("STG")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
        self.meshMats = {}
        self.materials = {}
        
    def write_texture(self, texName, texSize):
        
        texture = open(texName, 'wb')
        texture.write(self.inFile.read(texSize))
        texture.close()
        
    def parse_textures(self):
        
        numTex = self.inFile.read_long()
        for i in xrange(numTex):
            length = self.inFile.read_short()
            texName = self.inFile.read_string(length)
            texName = texName[:-4] + ".dds"
            texSize = self.inFile.read_long()
            self.write_texture(texName, texSize)
    
    def parse_unk1(self):
        
        unkCount = self.inFile.read_long()
        for i in xrange(unkCount):
            self.inFile.read_long()
        unk1 = self.inFile.read_short()
        if unk1 == 0:
            self.inFile.read_float()
        else:
            self.inFile.read_byte(23)
            numCount = self.inFile.read_long()
            for i in xrange(numCount):
                self.inFile.read_float(5)
                self.inFile.read_byte()
            numCount = self.inFile.read_long()
            for i in xrange(numCount):
                self.inFile.read_long(2)
                self.inFile.read_float(8)
            self.inFile.read_byte()
            self.inFile.read_float()
    
    def parse_meshes(self, numMesh):
        
        for i in xrange(numMesh):
            length = self.inFile.read_ushort()
            meshName = self.inFile.read_string(length)
            self.create_object(meshName)
            unk1, numVerts = self.inFile.read_long(2)
            self.inFile.read_byte()
            self.parse_vertices(meshName, numVerts)
            
            unk2, numSections = self.inFile.read_long(2)
            numFaces = self.inFile.read_long() / 3
            self.parse_faces(meshName, numFaces)
            self.inFile.read_long()
            length = self.inFile.read_short()
            matName = self.inFile.read_string(length)
            self.meshMats[meshName] = matName
            self.parse_unk1()
    
    def parse_materials(self, numMat):
        
        print numMat, "materials"
        for i in xrange(numMat):
            self.inFile.read_float(16)
            self.inFile.read_long()
            length = self.inFile.read_short()
            matName = self.inFile.read_string(length)
            self.inFile.read_long(5)
            numTex = self.inFile.read_long()
            textures = []
            for j in xrange(numTex):
                length = self.inFile.read_short()
                texName = self.inFile.read_string(length)
                textures.append(texName)
                
            self.materials[matName] = i
            self.create_material(i)
            self.add_material_name(i, matName)
            if textures:
                self.add_texture_name(i, textures[0])
                
    def assign_materials(self):
        '''Each key in faceNames gives the mesh it is assigned to'''
        
        for meshName in self.meshMats:
            matName = self.meshMats[meshName]
            matIndex = self.materials[matName]
            for j in xrange(self.face_count(meshName)):
                self.add_face_material(meshName, j, matIndex)
    
    def parse_vertices(self, meshName, numVerts):
        
        for i in xrange(numVerts):
            vx, vy, vz, nx, ny, nz, unk, tu, tv, \
              = self.inFile.read_float(9)
            
            self.create_vertex(meshName, i)
            vx *= -1
            self.add_coords(meshName, i, [vx, vy, vz])
            self.add_vert_uv(meshName, i, [tu, tv])
    
    def parse_faces(self, meshName, numFaces):
        
        for i in xrange(numFaces):
            v1, v2, v3 = self.inFile.read_short(3)
            self.create_face(meshName, i)
            self.add_face_verts(meshName, i, [v1, v2, v3])
        
    def parse_file(self):
        '''Main parser method. Can be replaced'''
        
        self.inFile.read_float()
        length = self.inFile.read_short()
        self.inFile.read_string(length)
        numMesh = self.inFile.read_ulong()
        print numMesh, "meshes"
        self.inFile.read_float()
        self.parse_meshes(numMesh)
        
        #read too much for the last mesh
        self.inFile.seek(-4, 1)
        self.parse_textures()
        
        #materials
        numMat = self.inFile.read_long()
        self.parse_materials(numMat)
        
        #assign materials to faces
        self.assign_materials()
        
        print self.inFile.tell()
        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = FatalFake_STG(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

def definitions():
    '''Return the header, extension, and a description of the format'''
    
    return "", "STG", "Fatal Fake STG"

if __name__ == '__main__':
    
    file1 = ""
    obj = read_file(file1)